import java.util.Objects;

/**
 * 学生类，用于表示一个学生的基本信息。
 * 包含学生的学号、姓名、性别、年龄和所在班级等属性。
 */
public class Student {
    // 属性（成员变量）
    private String studentId;
    private String name;
    private String gender;
    private int age;
    private String className;

    /**
     * 默认构造函数，创建一个空的学生对象。
     */
    public Student() {
        // 默认构造函数
    }

    /**
     * 带参构造函数，初始化学生的所有基本信息。
     *
     * @param studentId 学号，不能为空
     * @param name      姓名，不能为空
     * @param gender    性别，只能是"男"或"女"
     * @param age       年龄，应在0到150之间
     * @param className 班级名称，不能为空
     */
    public Student(String studentId, String name, String gender, int age, String className) {
        setStudentId(studentId);
        setName(name);
        setGender(gender);
        setAge(age);
        setClassName(className);
    }

    /**
     * 获取学生的学号。
     *
     * @return 返回当前学生的学号
     */
    public String getStudentId() {
        return studentId;
    }

    /**
     * 获取学生的姓名。
     *
     * @return 返回当前学生的姓名
     */
    public String getName() {
        return name;
    }

    /**
     * 获取学生的性别。
     *
     * @return 返回当前学生的性别
     */
    public String getGender() {
        return gender;
    }

    /**
     * 获取学生的年龄。
     *
     * @return 返回当前学生的年龄
     */
    public int getAge() {
        return age;
    }

    /**
     * 获取学生所在的班级名称。
     *
     * @return 返回当前学生所在的班级名称
     */
    public String getClassName() {
        return className;
    }

    /**
     * 设置学生的学号。
     *
     * @param studentId 要设置的学号，不能为null或空字符串
     * @throws IllegalArgumentException 当学号为空时抛出异常
     */
    public void setStudentId(String studentId) {
        if (studentId == null || studentId.isEmpty()) {
            throw new IllegalArgumentException("学号不能为空");
        }
        this.studentId = studentId;
    }

    /**
     * 设置学生的姓名。
     *
     * @param name 要设置的姓名，不能为null或空字符串
     * @throws IllegalArgumentException 当姓名为空时抛出异常
     */
    public void setName(String name) {
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("姓名不能为空");
        }
        this.name = name;
    }

    /**
     * 设置学生的性别。
     *
     * @param gender 要设置的性别，必须是"男"或"女"
     * @throws IllegalArgumentException 当性别不是"男"或"女"时抛出异常
     */
    public void setGender(String gender) {
        if (!"男".equals(gender) && !"女".equals(gender)) {
            throw new IllegalArgumentException("性别只能为'男'或'女'");
        }
        this.gender = gender;
    }

    /**
     * 设置学生的年龄。
     *
     * @param age 要设置的年龄，应在0到150之间
     * @throws IllegalArgumentException 当年龄不在合法范围内时抛出异常
     */
    public void setAge(int age) {
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("年龄应在0~150之间");
        }
        this.age = age;
    }

    /**
     * 设置学生所在的班级名称。
     *
     * @param className 要设置的班级名称，不能为null或空字符串
     * @throws IllegalArgumentException 当班级名称为空时抛出异常
     */
    public void setClassName(String className) {
        if (className == null || className.isEmpty()) {
            throw new IllegalArgumentException("班级名称不能为空");
        }
        this.className = className;
    }

    /**
     * 将学生信息转换为字符串格式输出。
     *
     * @return 格式化后的学生信息字符串
     */
    @Override
    public String toString() {
        return "学号: " + studentId +
                ", 姓名: " + name +
                ", 性别: " + gender +
                ", 年龄: " + age +
                ", 班级: " + className;
    }

    /**
     * 判断两个学生对象是否相等。
     * 比较依据包括：学号、姓名、性别、年龄和班级名称。
     *
     * @param o 要比较的对象
     * @return 如果两个学生对象相等则返回true，否则返回false
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Student)) return false;
        Student student = (Student) o;
        return age == student.age &&
               Objects.equals(studentId, student.studentId) &&
               Objects.equals(name, student.name) &&
               Objects.equals(gender, student.gender) &&
               Objects.equals(className, student.className);
    }

    /**
     * 计算学生对象的哈希码。
     * 基于学号、姓名、性别、年龄和班级名称进行计算。
     *
     * @return 当前学生对象的哈希码
     */
    @Override
    public int hashCode() {
        return Objects.hash(studentId, name, gender, age, className);
    }
}
